package edu.hawaii.myisern.action;

import edu.hawaii.myisern.model.MyIsernModel;
import java.util.List;
import edu.hawaii.myisern.researchers.jaxb.Researcher;
import net.sourceforge.stripes.action.ActionBean;
import net.sourceforge.stripes.action.ActionBeanContext;
import net.sourceforge.stripes.action.ForwardResolution;
import net.sourceforge.stripes.action.RedirectResolution;
import net.sourceforge.stripes.action.Resolution;


/**
 * Allows for a researcher to be added or edited. 
 * 
 * @author Ed Kim
 * @author Jon Lao
 * @author JianFei Liao
 * @author Jared Sunouchi
 */
public class ResearcherActionBean implements ActionBean {
  /** Required by the ActionBean interface. */
  private ActionBeanContext context;
  /** An error string, always displayed, but invisible if empty. */
  private String errorMessage = "";
  /** Added? */
  private boolean added;
  /** Editing? */
  private boolean editing;
  /** Edited? */
  private boolean edited;
  /** The single MyIsern instance manipulated by all webapp users. */
  private MyIsernModel myIsern = MyIsernModel.getInstance();
  /** Researcher attributes */
  private String name;
  private String organization;
  private String email;
  private String pictureLink;
  private String bioStatement;
  
  private String organizationNamesList;
  private String researcherNamesList;
  private static final String ADD_RES_PAGE = "/addResearcher.jsp";
  private static final String EDIT_RES_PAGE = "/editResearcher.jsp";
  private static final String EMPTY_STRING = "";
  private static final String HOME_PAGE = "/home.jsp";
  
  /** Variable from jsp pages used to find researcher */
  private String linkItem = " ";
 
  /**
   * Returns the context. Required by the interface. 
   * 
   * @return the ActionBeanContext.
   */
  public ActionBeanContext getContext() {
    return context;
  }
  
  /**
   * Sets the context. Required by the interface. 
   * 
   * @param context The ActionBeanContext to set. 
   */
  public void setContext(ActionBeanContext context) {
    this.context = context;
  }
  
  /**
   * Returns the error message, which may be empty.
   * Indicates if an error was made adding or editing the researcher. 
   * 
   * @return The error message. 
   */
  public String getErrorMessage() {
    return this.errorMessage;
  }
  
  /**
   * Returns the whether the researcher has been added or not.
   * 
   * @return Whether the researcher has been added or not. 
   */
  public boolean getAdded() {
    return this.added;
  }
  
  /**
   * Returns the whether the researcher has been edited or not.
   * 
   * @return Whether the researcher has been edited or not. 
   */
  public boolean getEdited() {
    return this.edited;
  }
  
  /**
   * Returns the whether the researcher is being edited or not.
   * 
   * @return Whether the researcher is being edited or not. 
   */
  public boolean getEditing() {
    return this.editing;
  }
  
  /**
   * Returns the string representation that will be used to generate the javascript array.
   * 
   * @return The string representation that will be used to generate the javascript array. 
   */
  public String getOrganizationNamesList() {
    this.organizationNamesList = myIsern.getOrganizationNamesList();
    return this.organizationNamesList;
  }
  
  /**
   * Returns the string representation that will be used to generate the javascript array.
   * 
   * @return The string representation that will be used to generate the javascript array. 
   */
  public String getResearcherNamesList() {
    this.researcherNamesList = myIsern.getResearcherNamesList();
    return this.researcherNamesList;
  }
  
//  /**
//   * Displays the form to add a researcher.
//   * 
//   * @return A Resolution indicating to redisplay the add.jsp page.
//   */
//  public Resolution researcherForm() {
//    return new ForwardResolution(ADD_RES_PAGE);
//  }
  
  /**
   * Displays the form to edit a researcher.
   * 
   * @return A Resolution indicating to redisplay the edit.jsp page.
   */
  public Resolution editResearcherForm() {
    return new ForwardResolution(EDIT_RES_PAGE);
  }
  
  /**
   * Resets the researcher data.
   */
  public void resetData() {
    this.setName("");
    this.setOrganization("");
    this.setEmail("");
    this.setPictureLink("");
    this.setBioStatement("");
  }
  
  /**
   * Clears the text in the text boxes.
   * 
   * @return A Resolution indicating to redirect to the add.jsp page.
   */
  public Resolution reset() {
    this.resetData();
    return new RedirectResolution(ADD_RES_PAGE).flash(this);
  }
  
  /**
   * Clears the text in the text boxes.
   * 
   * @return A Resolution indicating to redirect to the home.jsp page.
   */
  public Resolution cancel() {
    return new RedirectResolution(HOME_PAGE);
  }
  
  /**
   * Sets the name of the researcher.
   * 
   * @param name The name to set.
   */
  public void setName(String name) {
    this.name = name.trim();
  }
  
  /**
   * Returns the name of the researcher.
   * 
   * @return The name of the researcher.
   */
  public String getName() {
    return this.name;
  }
  
  /**
   * Sets the organization of the researcher.
   * 
   * @param organization The organization to set.
   */
  public void setOrganization(String organization) {
    this.organization = organization.trim();
  }
  
  /**
   * Returns the organization of the researcher.
   * 
   * @return The organization of the researcher.
   */
  public String getOrganization() {
    return this.organization;
  }
  
  /**
   * Sets the email of the researcher.
   * 
   * @param email The email to set.
   */
  public void setEmail(String email) {
    this.email = email.trim();
  }
  
  /**
   * Returns the email of the researcher.
   * 
   * @return The email of the researcher.
   */
  public String getEmail() {
    return this.email;
  }
  
  /**
   * Sets the picture-link of the researcher.
   * 
   * @param pictureLink The picture-link to set.
   */
  public void setPictureLink(String pictureLink) {
    this.pictureLink = pictureLink.trim();
  }
  
  /**
   * Returns the picture-link of the researcher.
   * 
   * @return The picture-link of the researcher.
   */
  public String getPictureLink() {
    return this.pictureLink;
  }
  
  /**
   * Sets the bio-statement of the researcher.
   * 
   * @param bioStatement The bio-statement to set.
   */
  public void setBioStatement(String bioStatement) {
    this.bioStatement = bioStatement.trim();
  }
  
  /**
   * Returns the bio-statement of the researcher.
   * 
   * @return The bio-statement of the researcher.
   */
  public String getBioStatement() {
    return this.bioStatement;
  }
  
  /**
   * Adds a researcher.
   * 
   * @return A Resolution indicating to redisplay the add.jsp page.
   * @throws Exception If problems occur.
   */
  public Resolution add() throws Exception {
    if (this.name == null) {
      this.errorMessage = "Please enter a name.";
    }
    else {
      List<Researcher> list = myIsern.getResearchersList();
      boolean found = false;
      for (Researcher researcher : list) {
        if (researcher.getName().equals(this.name.replace('_', ' '))) {
          found = true;
        }
      }

      if (found) {
        this.errorMessage = "Researcher already exists. Please edit instead.";
        this.editing = true;
        Researcher researcher = this.myIsern.getSingleResearcher(this.name);
        this.organization = researcher.getOrganization();
        this.email = researcher.getEmail();
        this.pictureLink = researcher.getPictureLink();
        this.bioStatement = researcher.getBioStatement();
        return new RedirectResolution(EDIT_RES_PAGE).flash(this);
      }
      else {
        Researcher newResearcher = new Researcher();
        newResearcher.setName(this.name);
        if (this.organization == null) {
          newResearcher.setOrganization(EMPTY_STRING);
        }
        else {
          newResearcher.setOrganization(this.organization);
        }
        if (this.email == null) {
          newResearcher.setEmail(EMPTY_STRING);
        }
        else {
          newResearcher.setEmail(this.email);
        }
        if (this.pictureLink == null) {
          newResearcher.setPictureLink(EMPTY_STRING);
        }
        else {
          newResearcher.setPictureLink(this.pictureLink);
        }
        if (this.bioStatement == null) {
          newResearcher.setBioStatement(EMPTY_STRING);
        }
        else {
          newResearcher.setBioStatement(this.bioStatement);
        }
        myIsern.addOrEditResearcher(newResearcher);
        this.added = true;
      }
    }
    return new ForwardResolution(ADD_RES_PAGE);
  }
  
  /**
   * Displays the information to edit.
   * 
   * @return A resolution indicating to redisplay the edit.jsp page.
   * @throws Exception If problems occur.
   */
  public Resolution displayEdit() throws Exception {
    if (this.name == null) {
      this.errorMessage = "Please enter a name.";
    }
    else {
      List<Researcher> list = myIsern.getResearchersList();
      Researcher editResearcher = new Researcher();
      boolean found = false;
      for (Researcher researcher : list) {
        if (researcher.getName().equals(this.name.replace('_', ' '))) {
          editResearcher = researcher;
          found = true;
        }
      }

      if (found) {
        this.organization = editResearcher.getOrganization();
        this.email = editResearcher.getEmail();
        this.pictureLink = editResearcher.getPictureLink();
        this.bioStatement = editResearcher.getBioStatement();

        this.editing = true;
      }
      else {
        this.errorMessage = "Name was not found.";
      }
    }
    return new ForwardResolution(EDIT_RES_PAGE);
  }
  
  /**
   * Edits a researcher.
   * 
   * @return A resolution indicating to redisplay the edit.jsp page.
   * @throws Exception If problems occur.
   */
  public Resolution edit() throws Exception {
    List<Researcher> list = myIsern.getResearchersList();
    Researcher editResearcher = new Researcher();
    for (Researcher researcher : list) {
      if (researcher.getName().equals(this.name.replace('_', ' '))) {
        editResearcher = researcher;
      }
    }
    
    if (this.organization == null) {
      editResearcher.setOrganization(EMPTY_STRING);
    }
    else {
      editResearcher.setOrganization(this.organization);
    }
    if (this.email == null) {
      editResearcher.setEmail(EMPTY_STRING);
    }
    else {
      editResearcher.setEmail(this.email);
    }
    if (this.pictureLink == null) {
      editResearcher.setPictureLink(EMPTY_STRING);
    }
    else {
      editResearcher.setPictureLink(this.pictureLink);
    }
    if (this.bioStatement == null) {
      editResearcher.setBioStatement(EMPTY_STRING);
    }
    else {
      editResearcher.setBioStatement(this.bioStatement);
    }
    myIsern.addOrEditResearcher(editResearcher);
    this.edited = true;
    this.editing = true;
    return new ForwardResolution(EDIT_RES_PAGE);
  }
  
  /**
   * Removes the researcher.
   * 
   * @return A resolution indicating to redisplay the add.jsp or edit.jsp page.
   * @throws Exception If problems occur.
   */
  public Resolution remove() throws Exception {    
    myIsern.removeResearcher(this.name);
    
    this.errorMessage = this.name + " has been removed.";
    return new ForwardResolution(ADD_RES_PAGE);
  }
    
  /**
   * Sets the link item variable from jsp pages.
   * 
   * @param string The new invalid organization link.
   */
  public void setLinkItem(String string) {
    this.linkItem = string;
  }
    
  /**
   * Finds the researcher by name from jsp link item variable.
   * Redirects to Add researcher if it doesn't exist or
   * Edit researcher if it does.
   * 
   * @return resolution either to editing or adding the researcher.
   */
  public Resolution linkToResearcher() {
   Researcher r = this.myIsern.getSingleResearcher(this.linkItem);
   if (r == null) {
     this.name = this.linkItem;
     this.added = false;
     return new RedirectResolution(ADD_RES_PAGE).flash(this);
   }
   else {
     this.name = this.linkItem;
     this.organization = r.getOrganization();
     this.email = r.getEmail();
     this.pictureLink = r.getPictureLink();
     this.bioStatement = r.getBioStatement();
     this.edited = false;
     this.editing = true;
     return new RedirectResolution(EDIT_RES_PAGE).flash(this);
   }
 }
}
